package com.atom.common.util;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;

import com.atom.common.entity.bo.JsonDiagram;

/**
 * Title: JsonDiagramGenerateUtil
 * Description: 生成前端流程图展示依赖的静态JSON文件，用来定义图形位置与大小
 * 修改inputFile和outputFile然后运行main函数
 * 
 * @author WEWE
 * @date 2016年9月22日 上午10:06:14
 * @version 1.0
 */
public class JsonDiagramGenerateUtil {

  static Logger logger = Logger.getLogger(JsonDiagramGenerateUtil.class);

  static Namespace bpmndi = Namespace.get("bpmndi", "http://www.omg.org/spec/BPMN/20100524/DI");
  static Namespace omgdc = Namespace.get("omgdc", "http://www.omg.org/spec/DD/20100524/DC");
  static Namespace omgdi = Namespace.get("omgdi", "http://www.omg.org/spec/DD/20100524/DI");
  static QName bpmndi_BPMNDiagram = new QName("BPMNDiagram", bpmndi);
  static QName bpmndi_BPMNPlane = new QName("BPMNPlane", bpmndi);
  static QName bpmndi_BPMNShape = new QName("BPMNShape", bpmndi);
  static QName bpmndi_BPMNEdge = new QName("BPMNEdge", bpmndi);
  static QName omgdc_Bounds = new QName("Bounds", omgdc);
  static QName omgdi_waypoint = new QName("waypoint", omgdi);

  static String inputFile = "C:/WORKSPACE/Workspaces_workflow/utilize/atom/atom-sdmuseum/src/main/resources/diagrams/藏品入账/main.bpmn";
  static String outputFile = "C:\\test\\cprz.json";

  /**
   * Description: 
   * @param args 
   */
  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
    SAXReader reader = new SAXReader();
    File diagramFile = new File(inputFile);
    Document bpmn;
    try {
      bpmn = reader.read(diagramFile);    
      Element root = bpmn.getRootElement();
      Element process = root.element("process");
      List<Element> tasks = process.elements();
      Map<String, JsonDiagram> maps = new HashMap<String, JsonDiagram>();
      for (Element task : tasks) {
        if (task.attributeValue("id") == null) {
          continue;
        }
        if (task.attributeValue("id").equals("subprocess1")) {
          write(task, maps);
          List<Element> subtasks = task.elements();
          for (Element subtask : subtasks) {            
            write(subtask, maps);
          }
          continue;
        }
        write(task, maps);
      }
      Element BPMNDiagram = root.element(bpmndi_BPMNDiagram);
      Element BPMNPlane = BPMNDiagram.element(bpmndi_BPMNPlane);
      List<Element> shapes = BPMNPlane.elements();
      for (Element shape : shapes) {
        if(shape.getQName().equals(bpmndi_BPMNShape)) {
          JsonDiagram diagram = maps.get(shape.attributeValue("bpmnElement"));
          Element e = shape.element(omgdc_Bounds);
          diagram.setShapeH(Float.valueOf(e.attributeValue("height")));
          diagram.setShapeW(Float.valueOf(e.attributeValue("width")));
          diagram.setShapeXY(Float.valueOf(e.attributeValue("x")), Float.valueOf(e.attributeValue("y")));
        }
        if(shape.getQName().equals(bpmndi_BPMNEdge)) {
          JsonDiagram diagram = maps.get(shape.attributeValue("bpmnElement"));
          List<Element> xys = shape.elements();
          for(Element xy : xys) {
            if(xy.getQName().equals(omgdi_waypoint)) {
              diagram.setShapeXY(Float.valueOf(xy.attributeValue("x")), Float.valueOf(xy.attributeValue("y")));
            }
          }
        }
      }
      String json = JsonUtil.ObjectToJsonQuietly(maps); 
      FileOutputStream fos = new FileOutputStream(outputFile); 
      fos.write(json.getBytes()); 
      fos.close();
      System.out.println("Generate Json Diagram Success");
    } catch (Exception e1) {      
      System.out.println("Generate Json Diagram Failed");
      e1.printStackTrace();
    }
  }
  
  private static void write(Element task, Map<String, JsonDiagram> maps) {
    JsonDiagram diagram = new JsonDiagram();
    diagram.setId(task.attributeValue("id"));
    diagram.setName(task.attributeValue("name"));
    diagram.setShapeC(task.getName());
    diagram.setSourceRef(task.attributeValue("sourceRef"));
    diagram.setTargetRef(task.attributeValue("targetRef"));
    maps.put(task.attributeValue("id"), diagram);
  }
}
